<?php

function sendcommand($sock, $rawcmd) {
	$rawcmd = censor($rawcmd);
	if ($rawcmd) {
		logline($rawcmd, true);
		flush();
		fputs($sock, $rawcmd);
	} else {
		echo "<i>ERROR DETECTED</i><br />";
		flush();
	}
}
function sendcommands($sock, $rawcmds) {
	$rawcmds = array_map("censor", $rawcmds);
	foreach ($rawcmds as $rawcmd) {
		if ($rawcmd) {
			logline($rawcmd, true);
			flush();
			fputs($sock, $rawcmd);
		} else {
			echo "<i>ERROR DETECTED</i><br />";
			flush();
		}
		sleep(0.15);
	}
}
function whatmode($text) {
	$ex = explode(" ", $text);
	$ex = array_map("trim", $ex);
	if ($ex[1] != "MODE") {
		return;
	}
	$returnstring = trim(substr($ex[0], 1, strpos($ex[0], "!") - 1));
	$modestrings = array();
	if ($ex[4]) {
		foreach (str_split($ex[3]) as $mode) {
			if ($mode == "+") {
				$modetype = 1;
				continue;
			} elseif ($mode == "-") {
				$modetype = 2;
				continue;
			} elseif ($mode == "o") {
				if ($modetype == 1) {
					$modestring = "gave operator status to {USER}";
				} elseif ($modetype == 2) {
					$modestring = "took away operator status from {USER}";
				}
			} elseif ($mode == "e") {
				if ($modetype == 1) {
					$modestring = "added a {TRIBANMUTE} exception for {USER}";
				} elseif ($modetype == 2) {
					$modestring = "took away {USER}'s {TRIBANMUTE} exception";
				}
			} elseif ($mode == "v") {
				if ($modetype == 1) {
					$modestring = "gave VIP status to {USER}";
				} elseif ($modetype == 2) {
					$modestring = "took away VIP status from {USER}";
				}
			} elseif ($mode == "b") {
				if ($modetype == 1) {
					$modestring = "{BANMUTED} {USER}";
				} elseif ($modetype == 2) {
					$modestring = "un{BANMUTED} {USER}";
				}
			} elseif ($mode == "l") {
				if ($modetype == 1) {
					$modestring = "set the limit to {USER} users";
				}
			} else {
				if ($modetype == 1) {
					$modestring = "added mode ".$mode." to {USER}";
				} elseif ($modetype == 2) {
					$modestring = "took away mode ".$mode." from {USER}";
				}
			}
			$modestrings[] = $modestring;
		}
		$stringsfinal = array();
		for ($i = 4; $i < count($ex); $i++) {
			$modestring = $modestrings[$i - 4];
			if (strpos($modestring, "{BANMUTED}") !== false) {
				$banmuted = ((strpos($ex[$i], "%") === 0) ? "muted" : "banned");
				if (strpos($ex[$i], "%") === 0) {
					$ex[$i] = substr($ex[$i], 1);
				}
			}
			if (strpos($modestring, "{TRIBANMUTE}") !== false) {
				$tribanmute = ((strpos($ex[$i], "?") === 0) ? "ban and mute" : ((strpos($ex[$i], "%") === 0) ? "mute" : "ban"));
				if (strpos($ex[$i], "%") === 0) {
					$ex[$i] = substr($ex[$i], 1);
				}
			}
			if (strpos($ex[$i], "*!*@") === 0) {
				$username = "the hostname \"".substr($ex[$i], 4)."\"";
			} else {
				$username = preg_replace("/!\*@\*$/", '', $ex[$i]);
			}
			$stringsfinal[] = str_replace(array("{USER}", "{BANMUTED}", "{TRIBANMUTE}"), array($username, $banmuted, $tribanmute), $modestring);
		}
		$stringsfinal = array_filter(array_map("trim", $stringsfinal));
		$returnstring .= " ".implode(", ", $stringsfinal);
	} else {
		foreach (str_split($ex[3]) as $mode) {
			if ($mode == "+") {
				$modetype = 1;
				continue;
			} elseif ($mode == "-") {
				$modetype = 2;
				continue;
			} elseif ($mode == "c") {
				if ($modetype == 1) {
					$modestring = "blocked formatting from the channel";
				} elseif ($modetype == 2) {
					$modestring = "unblocked formatting from the channel";
				}
			} elseif ($mode == "i") {
				if ($modetype == 1) {
					$modestring = "made the channel invite only";
				} elseif ($modetype == 2) {
					$modestring = "made it possible to enter the channel without an invitation";
				}
			} elseif ($mode == "k") {
				if ($modetype == 1) {
					$modestring = "made the channel password protected";
				} elseif ($modetype == 2) {
					$modestring = "took away password protection from the channel";
				}
			} elseif ($mode == "l") {
				if ($modetype == 2) {
					$modestring = "took away the user limit from the channel";
				}
			} elseif ($mode == "m") {
				if ($modetype == 1) {
					$modestring = "muted the channel";
				} elseif ($modetype == 2) {
					$modestring = "unmuted the channel";
				}
			} elseif ($mode == "M") {
				if ($modetype == 1) {
					$modestring = "limited the channel to registered users";
				} elseif ($modetype == 2) {
					$modestring = "allowed unregistered users to speak in the channel";
				}
			} elseif ($mode == "n") {
				if ($modetype == 1) {
					$modestring = "blocked messages from users outside of the channel";
				} elseif ($modetype == 2) {
					$modestring = "allowed messages from users outside of the channel";
				}
			} elseif ($mode == "O") {
				if ($modetype == 1) {
					$modestring = "limited the channel to IRCOperators";
				} elseif ($modetype == 2) {
					$modestring = "allowed non-IRCOperators into the channel";
				}
			} elseif ($mode == "p" || $mode == "s") {
				if ($modetype == 1) {
					$modestring = "made the channel unsearchable";
				} elseif ($modetype == 2) {
					$modestring = "made the channel searchable";
				}
			} elseif ($mode == "R") {
				if ($modetype == 1) {
					$modestring = "blocked unregistered users from the channel";
				} elseif ($modetype == 2) {
					$modestring = "allowed unregistered users into the channel";
				}
			} elseif ($mode == "t") {
				if ($modetype == 1) {
					$modestring = "protected the topic";
				} elseif ($modetype == 2) {
					$modestring = "removed protection from the topic";
				}
			} else {
				if ($modetype == 1) {
					$modestring = "added mode ".$mode." to the channel";
				} elseif ($modetype == 2) {
					$modestring = "took away mode ".$mode." from the channel";
				}
			}
			$stringsfinal[] = $modestring;
		}
		$stringsfinal = array_filter(array_map("trim", $stringsfinal));
		$returnstring .= " ".implode(", ", $stringsfinal);
	}
	return $returnstring."\n";
}
function autokick($sock, $name, $reason) {
	if (strpos($name, "haggisbot!n=haggisbo@mke-69-97-")) {
		return;
	}
	global $bans;
	if (strpos($name, "@gateway/web/ajax/mibbit.com/")) {
		foreach ($bans as  $ban) {
			if ($ban[0] == "*!".substr($name, strpos($name, "!") + 1, -16)."*") {
				return;
			}
		}
		foreach ($bans as  $ban) {
			if ($ban[0] == "%*!*@".substr($name, strpos($name, "@") + 1)) {
				$rawcmd = "MODE #bostonglob +b *!".substr($name, strpos($name, "!") + 1, -16)."*\n";
				fputs($sock, $rawcmd);
				logline(censor($rawcmd), true);
				$rawcmd = "KICK #bostonglob ".substr($name, 1, strpos($name, "!") - 1)." :".$reason." [autokick]\n";
				fputs($sock, $rawcmd);
				logline(censor($rawcmd), true);
				$bans[] = array("*!".substr($name, strpos($name, "!") + 1, -16)."*", time() + 300);
				return;
			}
		}
		$rawcmd = "MODE #bostonglob +b %*!".substr($name, strpos($name, "!") + 1, -16)."*\n";
		fputs($sock, $rawcmd);
		logline(censor($rawcmd), true);
		$rawcmd = "KICK #bostonglob ".substr($name, 1, strpos($name, "!") - 1)." :".$reason." [autokick]\n";
		fputs($sock, $rawcmd);
		logline(censor($rawcmd), true);
		$bans[] = array("%*!".substr($name, strpos($name, "!") + 1, -16)."*", time() + 300);
	} else {
		foreach ($bans as  $ban) {
			if ($ban[0] == "*!*@".substr($name, strpos($name, "@") + 1)) {
				return;
			}
		}
		foreach ($bans as  $ban) {
			if ($ban[0] == "%*!*@".substr($name, strpos($name, "@") + 1)) {
				$rawcmd = "MODE #bostonglob +b *!*@".substr($name, strpos($name, "@") + 1)."\n";
				fputs($sock, $rawcmd);
				logline(censor($rawcmd), true);
				$rawcmd = "KICK #bostonglob ".substr($name, 1, strpos($name, "!") - 1)." :".$reason." [autokick]\n";
				fputs($sock, $rawcmd);
				logline(censor($rawcmd), true);
				$bans[] = array("*!*@".substr($name, strpos($name, "@") + 1), time() + 300);
				return;
			}
		}
		$rawcmd = "MODE #bostonglob +b %*!*@".substr($name, strpos($name, "@") + 1)."\n";
		fputs($sock, $rawcmd);
		logline(censor($rawcmd), true);
		$rawcmd = "KICK #bostonglob ".substr($name, 1, strpos($name, "!") - 1)." :".$reason." [autokick]\n";
		fputs($sock, $rawcmd);
		logline(censor($rawcmd), true);
		$bans[] = array("%*!*@".substr($name, strpos($name, "@") + 1), time() + 300);
	}
}
function censor($text) {
	$badwords = "whore?, f((\*|u)?ck|u[ck]), f.?­uck, sh[\*i]t, d[\*i]ck, [sc5][e3]x, \bass(hole)?\b, pen[\!1i]s, \bp([0o]r|r[0o])n\b, bitch";
	$badwords = explode(',', $badwords);
	$badwords = array_map('trim', $badwords);
	$badwords = implode('|', $badwords);
	$matches = array();
	preg_match("#$badwords#i", $text , $matches);
	$matchesreplace = array();
	foreach ($matches as $match) {
		$matchesreplace[] = str_repeat("*", strlen($match));
	}
	return str_replace($matches, $matchesreplace, $text);
}
function ircrainbow($text, $bold, $dark = null) {
	$returnstring = "";
	if ($bold) {
		$returnstring .= "";
	}
	$returnstring .= "0,1";
	$coloron = 1;
	foreach (str_split($text) as $ircchar) {
		$returnstring .= (($coloron == 1) ? "04" : (($coloron == 2) ? "07" : (($coloron == 3) ? "08" : (($coloron == 4) ? "09" : (($coloron == 5) ? "11" : "13")))));
		$returnstring .= $ircchar;
		if ($coloron == 6) {
			$coloron = 0;
		}
		$coloron++;
	}
	return $returnstring;
}
function checkauth($data, $name = false) {
	global $USERSINCHAT;
	if ($name) {
		$data = ltrim($data, "+@");
		if (stripos(" ".$USERSINCHAT." ", " @".$data." ") !== false) {
			return true;
		}
	} else {
		foreach (explode(" ", $USERSINCHAT) as $user) {
			if (strtolower($user) == strtolower(substr($data, 1, strpos($data, "!") - 1))) {
				return false;
			} elseif (strtolower($user) == strtolower("@".substr($data, 1, strpos($data, "!") - 1)))  {
				return true;
			}
		}
	}
}
function checkvip($data, $name = false) {
	global $USERSINCHAT;
	if ($name) {
		$data = ltrim($data, "+@");
		if (stripos(" ".$USERSINCHAT." ", " +".$data." ") !== false) {
			return true;
		}
	} else {
		foreach (explode(" ", $USERSINCHAT) as $user) {
			if (strtolower($user) == strtolower("+".substr($data, 1, strpos($data, "!") - 1)))  {
				return true;
			} elseif (strtolower($user) == strtolower(substr($data, 1, strpos($data, "!") - 1))) {
				return false;
			}
		}
	}
}
function checkuser($name) {
	global $USERSINCHAT;
	$name = trim($name);
	$name = ltrim($name, "+@");
	if (stripos("  ".$USERSINCHAT." ", " ".$name." ")) {
		return substr($USERSINCHAT, stripos(" ".$USERSINCHAT." ", " ".$name." "), strlen($name));
	} elseif (stripos("  ".$USERSINCHAT." ", " +".$name." ")) {
		return substr($USERSINCHAT, stripos(" ".$USERSINCHAT." ", " +".$name." ") + 1, strlen($name));
	} elseif (stripos("  ".$USERSINCHAT." ", " @".$name." ")) {
		return substr($USERSINCHAT, stripos(" ".$USERSINCHAT." ", " @".$name." ") + 1, strlen($name));
	}
	return false;
}
function closechat($socket) {
	global $richlog, $plainlog, $bans;
	foreach ($bans as $ban_key => $ban) {
		sendcommand($socket, "MODE #bostonglob -b ".$ban[0]."\n");
		unset($bans[$ban_key]);
	}
	logtext("</div></body></html>", "");
	fclose($richlog);
	fclose($plainlog);
	fclose($socket);
	exit;
}
function logtext($text, $plaintext = NULL) {
	global $richlog, $plainlog;
	if ($plaintext === NULL)
		$plaintext = "[".date('g:i a')."] ".htmlspecialchars_decode($text);
	else
		$plaintext = "[".date('g:i a')."] ".$plaintext;
	echo $text;
	fwrite($richlog, $text);
	if ($plaintext === NULL) {
		fwrite($plainlog, htmlspecialchars_decode($text));
	} else {
		fwrite($plainlog, $plaintext);
	}
}
function ircformat($line) {
	$irccolors = array("#fff", "#000", "#008", "#080", "#f00", "#800", "#80f", "#f80", "#ff0", "#0f0", "#088", "#0ff", "#00f", "#f0f", "#888", "#ccc", "#fff", "transparent");
	$chararray = str_split(htmlspecialchars($line));
	$newchars = array();
	$boldon = $underlineon = $coloron = $bgcolor = false;
	global $thetime;
	// Order is always: bold > color > underline
	reset($chararray);
	while (list($charkey, $ircchar) = each($chararray)) {
		switch ($ircchar) {
			case "":
				$ircstring = "";
				if ($underlineon) {
					$ircstring .= "</u>";
				}
				if ($coloron) {
					$ircstring .= "</span>";
				}
				if ($boldon) {
					$ircstring .= "</b>";
				}
				$bgcolor = $coloron = $underlineon = $italicson = $boldon = false;
				$newchars[] = $ircstring;
				break;
			case "":
				$ircstring = "";
				if ($underlineon) {
					$ircstring .= "</u>";
				}
				if ($coloron) {
					$ircstring .= "</span>";
				}
				if ($boldon) {
					$ircstring .= "</b>";
				}
				if (!$boldon) {
					$ircstring .= "<b>";
				}
				if ($coloron) {
					$ircstring .= "<span style=\"color: ".$irccolors[$coloron[0]].((isset($coloron[1])) ? "; background-color: ".$irccolors[$coloron[1]] : "")."\">";
				}
				if ($underlineon) {
					$ircstring .= "<u>";
				}
				$boldon = (($boldon) ? false : true);
				$newchars[] = $ircstring;
				break;
			case "":
				$ircstring = "";
				if ($underlineon) {
					$ircstring .= "</u>";
				}
				if (!$underlineon) {
					$ircstring .= "<u>";
				}
				$underlineon = (($underlineon) ? false : true);
				$newchars[] = $ircstring;
				break;
			case "":
				$colorstring = "";
				if (ctype_digit($chararray[$charkey + 1])) {
					$colorstring .= $chararray[$charkey + 1];
					unset($chararray[$charkey + 1]);
					if (ctype_digit($chararray[$charkey + 2]) || $chararray[$charkey + 2] == ",") {
						$colorstring .= $chararray[$charkey + 2];
						unset($chararray[$charkey + 2]);
						if ((ctype_digit($chararray[$charkey + 3]) && substr($colorstring, 2, 1) == ",") || ($chararray[$charkey + 3] == "," && ctype_digit(substr($colorstring, 2, 1)))) {
							$colorstring .= $chararray[$charkey + 3];
							unset($chararray[$charkey + 3]);
							if ((ctype_digit($chararray[$charkey + 4]) && ctype_digit(substr($colorstring, 2, 1)) && substr($colorstring, 3, 1) == ",") || (ctype_digit($chararray[$charkey + 4]) && substr($colorstring, 2, 1) == "," && ctype_digit(substr($colorstring, 3, 1)))) {
								$colorstring .= $chararray[$charkey + 4];
								unset($chararray[$charkey + 4]);
								if ((ctype_digit($chararray[$charkey + 5]) && substr($colorstring, 3, 1) == ",")) {
									$colorstring .= $chararray[$charkey + 5];
									unset($chararray[$charkey + 5]);
								}
							}
						}
					}
					$ircstring = "";
					$ircstring .= (($underlineon) ? "</u>" : "");
					$ircstring .= (($coloron) ? "</span>" : "");
					$bgcolor = $coloron[1];
					$coloron = false;
					$coloron = explode(",", substr($colorstring, 1));
					$coloron[0] = intval($coloron[0]);
					$coloron[1] = ((isset($coloron[1])) ? intval($coloron[1]) : ((isset($bgcolor)) ? $bgcolor : 17));
					$ircstring .= "<span style=\"color: ".$irccolors[$coloron[0]]."; background-color: ".$irccolors[$coloron[1]].";\">";
					$ircstring .= (($underlineon) ? "<u>" : "");
					$newchars[] = $ircstring;
				} else {
					$ircstring = "";
					$ircstring .= (($underlineon) ? "</u>" : "");
					$ircstring .= (($coloron) ? "</span>" : "");
					$ircstring .= (($underlineon) ? "<u>" : "");
					$bgcolor = $coloron = false;
					$newchars[] = $ircstring;
					
				}
				break;
			default:
				$newchars[] = $ircchar;
		}
	}
	$ircstring = "";
	if ($coloron) {
		$ircstring .= "</span>";
	}
	if ($underlineon) {
		$ircstring .= "</u>";
	}
	if ($italicson) {
		$ircstring .= "</i>";
	}
	if ($boldon) {
		$ircstring .= "</b>";
	}
	$coloron = $underlineon = $italicson = $boldon = false;
	$line = implode($newchars, "").$ircstring;
	return str_replace(array(":)", ":-)", "&gt;:-(", "&gt;:(", ":-d", ":d", ":-D", ":D", ":-O", ":-o", ":o", ":-p", ":-P", ":p", ":P", ";-)", ";)", ":-(", ":(", ":-|", ":|", ":'(", ":$", ":-$", "(H)", "(h)", "8)", "(8", ":-@", ":@", ":-S", ":s", "O.O", "0.0", "o.o", ":?", "XD"), array("<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-smile.png\" alt=\":)\" title=\":)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-smile.png\" alt=\":-)\" title=\":-)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-angry.png\" alt=\"&gt;:-(\" title=\"&gt;:-(\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-angry.png\" alt=\"&gt;:(\" title=\"&gt;:(\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-laugh.png\" alt=\":-d\" title=\":-d\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-laugh.png\" alt=\":d\" title=\":d\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-lol.png\" alt=\":-D\" title=\":-D\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-lol.png\" alt=\":D\" title=\":D\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-dizzy.png\" alt=\":-O\" title=\":-O\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-dizzy-back.png\" alt=\":-o\" title=\":-o\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-surprised.png\" alt=\":o\" title=\":o\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-tongue.png\" alt=\":-P\" title=\":-P\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-tongue.png\" alt=\":-p\" title=\":-p\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-tongue.png\" alt=\":p\" title=\":p\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-tongue.png\" alt=\":P\" title=\":P\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-wink.png\" alt=\";-)\" title=\";-)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-wink.png\" alt=\";)\" title=\";)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-sad.png\" alt=\":-(\" title=\":-(\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-sad.png\" alt=\":(\" title=\":(\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-normal.png\" alt=\":-|\" title=\":-|\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-normal.png\" alt=\":|\" title=\":|\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-cry.png\" alt=\":'(\" title=\":'(\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-red.png\" alt=\":$\" title=\":$\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-red.png\" alt=\":-$\" title=\":-$\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-cool.png\" alt=\"(H)\" title=\"(H)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-cool.png\" alt=\"(h)\" title=\"(h)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-dizzy.png\" alt=\"8)\" title=\"8)\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-dizzy-back.png\" alt=\"(8\" title=\"(8\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-evil.png\" alt=\":-@\" title=\":-@\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-evil.png\" alt=\":@\" title=\":@\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-rolleyes.png\" alt=\":-S\" title=\":-S\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-rolleyes.png\" alt=\":s\" title=\":s\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-eek.png\" alt=\"O.O\" title=\"O.O\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-eek.png\" alt=\"0.0\" title=\"0.0\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-eek.png\" alt=\"o.o\" title=\"o.o\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-question.png\" alt=\":?\" title=\":?\" />", "<img src=\"http://www.the-boston-glob.co.cc/chat/img/face-rofl.png\" alt=\"XD\" title=\"XD\" />"), $line);
}
function logline($line, $isaidit = false) {
	$ircline = $line;
	if ($isaidit) {
		$ircline = ":haggisbot!n=haggisbo@haggis.the-boston-glob.co.cc ".$line;
	}
	if (strpos($ircline, "NOTICE haggisbot :*** Your host is ") === 0) {
		return;
	}
	// Remove the first colon
	$cmd = substr($ircline, 1);
	// Nickname of user who sent the command
	$nick = substr($cmd, 0, strpos($cmd, "!"));
	// The username
	$user = substr($cmd, (strpos($cmd, "n=") !== false) ? strpos($cmd, "n=") + 2 : 0, (strpos($cmd, "@") !== false) ? strpos($cmd, "@") : strpos($cmd, " "));
	// Hostname
	if (strpos($cmd, "n=".$user) === false) {
		$host = $user;
	} else {
		$host = substr($cmd, strpos($cmd, "@") + 1, strpos($cmd, " ") - strpos ($cmd, "@"));
	}
	// Get rid of the first portion of the command.
	$cmd = substr($cmd, strpos($cmd, " ") + 1);
	$action = substr($cmd, 0, strpos($cmd, " "));
	$cmd = substr($cmd, strpos($cmd, " ") + 1);
	$to = trim(substr($cmd, 0, strpos($cmd, ":")));
	$cmd = substr($cmd, strpos($cmd, ":") + 1);
	if (trim($line) == "NOTICE AUTH :*** Looking up your hostname..." || trim($line) == "NOTICE AUTH :*** Found your hostname" || trim($line) == "NOTICE AUTH :*** Found your hostname, welcome back" || trim($line) == "NOTICE AUTH :*** Checking ident" || trim($line) == "NOTICE AUTH :*** No identd (auth) response" || strpos(trim($line), "PING :") === 0 || strpos(trim($line), "PONG :") === 0 || trim($line) == ":services. MODE haggisbot :+e" || strpos(trim($line), ".freenode.net 901 haggisbot") || trim($action) == "332" || trim($action) == "333" || strpos(trim($line), ".freenode.net 477 haggisbot ") || strpos(trim($line), ".freenode.net 328 haggisbot #bostonglob :")) {
		return;
	}
	if ($isaidit) {
		if ($action == "USER") {
			logtext("Logging in...<br />", "Logging in...\n");
			flush();
			return;
		}
		if ($action == "NICK") {
			logtext("Authenticating...<br />", "Authenticating\n");
			flush();
			return;
		}
		if ($action == "PRIVMSG" && $to == "NickServ") {
			logtext("Authenticated!<br />", "Authenticated!\n");
			flush();
			return;
		}
		if ($action == "JOIN") {
			logtext("Joining the channel...<br />", "Joining the channel...\n");
			flush();
			return;
		}
		if ($action == "NAMES") {
			logtext("Refreshing user list...<br />", "Refreshing user list...\n");
			flush();
			return;
		}
		if ($action == "PRIVMSG" && strpos($cmd, "PING") === 0) {
			logtext("Pinging ".$to."...<br />", $ircline);
			flush();
			return;
		}
		if ($action == "NOTICE" && strpos($cmd, "PING") === 0) {
			logtext("Responding to ".$to."'s ping...<br />", $ircline);
			flush();
			return;
		}
	} elseif ($nick == "haggisbot") {
		return;
	}
	if ($action == "NOTICE" && $to == "haggisbot" && strpos($cmd, "PING") === 0) {
		logtext("Recieved ping reply from ".$nick.".<br />", $ircline);
		flush();
		return;
	}
	if ($action == "PRIVMSG" && $to == "haggisbot" && strpos($cmd, "PING") === 0) {
		logtext("Recieved ping from ".$nick.".<br />", $ircline);
		flush();
		return;
	}
	if (trim($cmd) == "VERSION") {
		echo logtext("Responding to version request from ".$nick."<br />", $ircline);
		return;
	}
	if (trim($cmd) == "VERSION HaggisBot 0.6 by Mad Haggis Enterprises (http://www.the-boston-glob.co.cc/)") {
		return;
	}
	if (ctype_digit($action)) {
		if (intval($action) < 4 || (intval($action) == 372)) {
			logtext("<code>".ircformat(trim($cmd))."</code><br />\n", $ircline);
		} elseif (intval($action) == 353) {
			logtext("Recieved user list<br />", $ircline);
		}
	} elseif ($action == "PRIVMSG") {
		if ($to == "#bostonglob") {
			if (strpos(trim($cmd), "ACTION") === 0) {
				logtext((($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." ".ircformat(substr(trim($cmd), 7, -1))."<br />", $ircline);
			} else {
				logtext("&lt;".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))."&gt; ".ircformat(trim($cmd))."<br />", $ircline);
			}
		} elseif ($to == "haggisbot") {
			if (strpos(trim($cmd), "ACTION") === 0) {
				logtext("<i>".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." ".ircformat(substr(trim($cmd), 7, -1))."</i><br />", $ircline);
			} else {
				logtext("<i>&lt;".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))."&gt; ".ircformat(trim($cmd))."</i><br />", $ircline);
			}
		} elseif ($nick == "haggisbot") {
			if (strpos(trim($cmd), "ACTION") === 0) {
				logtext("<i>".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($to, true)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($to, true)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$to.(($isaidit) ? "</b></span>" : ((checkauth($to, true)) ? "</b></span>" : ((checkvip($to, true)) ? "</b></span>" : "</b>")))." ".ircformat(substr(trim($cmd), 7, -1))."</i><br />", $ircline);
			} else {
				logtext("<i>&gt;".((checkauth($to, true)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($to, true)) ? "<span style=\"color: #00f\">+<b>" : "<b>")).$to.((checkauth($to, true)) ? "</b></span>" : ((checkvip($to, true)) ? "</b></span>" : "</b>"))."&lt; ".ircformat(trim($cmd))."</i><br />", $ircline);
			}
		} else {
			logtext(nl2br("<small>".ircformat($ircline)."</small>"), $ircline);
		}
	} elseif ($action == "NOTICE") {
		if ($to == "haggisbot") {
			if (strpos(trim($cmd), "ACTION") === 0) {
				logtext("<i>".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." ".ircformat(substr(trim($cmd), 7, -1))."</i><br />", $ircline);
			} else {
				logtext("<i>&lt;".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))."&gt; ".ircformat(trim($cmd))."</i><br />", $ircline);
			}
		} elseif ($nick == "haggisbot") {
			if (strpos(trim($cmd), "ACTION") === 0) {
				logtext("<i>".(($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($to, true)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($to, true)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$to.(($isaidit) ? "</b></span>" : ((checkauth($to, true)) ? "</b></span>" : ((checkvip($to, true)) ? "</b></span>" : "</b>")))." ".ircformat(substr(trim($cmd), 7, -1))."</i><br />", $ircline);
			} else {
				logtext("<i>&gt;".((checkauth($to, true)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($to, true)) ? "<span style=\"color: #00f\">+<b>" : "<b>")).$to.((checkauth($to, true)) ? "</b></span>" : ((checkvip($to, true)) ? "</b></span>" : "</b>"))."&lt; ".ircformat(trim($cmd))."</i><br />", $ircline);
			}
		} else {
			echo logtext(nl2br("<small>".ircformat($ircline)."</small>"), $ircline);
		}
	} elseif ($action == "INVITE") {
	} elseif ($action == "KICK") {
		$ex = explode(" ", $to);
		logtext((($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." has kicked ".(((checkauth(trim($ex[2]), true)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip(trim($ex[2]), true)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).trim($ex[3]).(((checkauth(trim($ex[2]), true)) ? "</b></span>" : ((checkvip(trim($ex[2]), true)) ? "</b></span>" : "</b>")))." from the chat. ".((trim($cmd)) ? "(".trim($cmd).")" : "")."<br />", $ircline);
	} elseif ($action == "MODE") {
	} elseif (strpos($line, ".freenode.net 366 haggisbot #bostonglob :End of /NAMES list.")) {
		logtext("", $ircline);
	} elseif (trim($action) == "QUIT" || trim($action) == "PART") {
		logtext((($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." has left the chat".((trim($cmd)) ? " (".trim($cmd).")" : "").".<br />", $ircline);
	} elseif (trim($action) == "JOIN") {
		logtext(((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>")).$nick.((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>"))." has joined the chat.<br />", $ircline);
	} elseif (trim($action) == "NICK") {
		$ex = explode(" ", trim($ircline));
		logtext((($isaidit) ? "<span style=\"color: indigo\">@<b>" : ((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>"))).$nick.(($isaidit) ? "</b></span>" : ((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")))." has changed their name to ".((checkauth($ircline)) ? "<span style=\"color: #f00\">@<b>" : ((checkvip($ircline)) ? "<span style=\"color: #00f\">+<b>" : "<b>")).trim(substr($ex[2], 1)).((checkauth($ircline)) ? "</b></span>" : ((checkvip($ircline)) ? "</b></span>" : "</b>")).".<br />", $ircline);
	} else {
		logtext(nl2br("<small>".ircformat($ircline)."</small>"), $ircline);
	}
	flush();
}
function respond($ircline, $response, $forceprivate = false) {
	// Remove the first colon
	$cmd = substr($ircline, 1);
	// Nickname of user who sent the command
	$nick = substr($cmd, 0, strpos($cmd, "!"));
	// The username
	$user = substr($cmd, (strpos($cmd, "n=") !== false) ? strpos($cmd, "n=") + 2 : 0, (strpos($cmd, "@") !== false) ? strpos($cmd, "@") : strpos($cmd, " "));
	// Hostname
	if (strpos($cmd, "n=".$user) === false) {
		$host = $user;
	} else {
		$host = substr($cmd, strpos($cmd, "@") + 1, strpos($cmd, " ") - strpos ($cmd, "@"));
	}
	// Get rid of the first portion of the command.
	$cmd = substr($cmd, strpos($cmd, " ") + 1);
	$action = substr($cmd, 0, strpos($cmd, " "));
	$cmd = substr($cmd, strpos($cmd, " ") + 1);
	$to = trim(substr($cmd, 0, strpos($cmd, ":")));
	$cmd = substr($cmd, strpos($cmd, ":") + 1);
	if ($forceprivate == true) {
		return "PRIVMSG $nick :$response\n";
	} elseif ($to == "haggisbot") {
		return "NOTICE $nick :$response\n";
	} elseif ($to == "#bostonglob") {
		return "PRIVMSG #bostonglob :$response\n";
	} else {
		return "";
	}
}
if (file_exists("I:/Documents and Settings/Benjamin/Desktop/BOSTON GLOB/Chat Logs/globlog-".date("y-m-d").".xhtml")) {
	$logalready = true;
}
$richlog = fopen("I:/Documents and Settings/Benjamin/Desktop/BOSTON GLOB/Chat Logs/globlog-".date("y-m-d").".xhtml", "a+");
$plainlog = fopen("I:/Documents and Settings/Benjamin/Desktop/BOSTON GLOB/Chat Logs/globlog-".date("y-m-d").".txt", "a+");
$kicked = false;

$currentdate = date('l, F jS, Y');
$bans = array();
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
if ($logalready) {
	ftruncate($richlog, filesize("I:/Documents and Settings/Benjamin/Desktop/BOSTON GLOB/Chat Logs/globlog-".date("y-m-d").".xhtml") - 20);
	fseek($richlog, 0, SEEK_END);
	echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Glob Chat log for ".date('l, F jS, Y')."</title></head><body style=\"background: #fbfbfb url('http://www.the-boston-glob.co.cc/images/cbg.jpg') repeat-x fixed bottom center\"><div style=\"white-space: nowrap;\"><h1 style=\"text-align: center;\">Glob Chat log for ".date('l, F j<\s\u\p><\u>S</\u></\s\u\p>, Y')."</h1>";
} else {
	logtext("<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Glob Chat log for ".date('l, F jS, Y')."</title></head><body style=\"background: #fbfbfb url('http://www.the-boston-glob.co.cc/images/cbg.jpg') repeat-x fixed bottom center\"><div style=\"white-space: nowrap;\"><h1 style=\"text-align: center;\">Glob Chat log for ".date('l, F j<\s\u\p><\u>S</\u></\s\u\p>, Y')."</h1>", "Glob Chat log for ".date('l, F jS, Y')."\n");
}
include "blowfish.class.php";
// Opening the socket
$socket = fsockopen("irc.freenode.net", 6667);
// Send auth info
sendcommand($socket, "USER haggisbot \"EMAIL\" haggisbot :HaggisBot 0.6 by Mad Haggis Enterprises\n");
sendcommand($socket, "NICK haggisbot\n");
sendcommand($socket, "PRIVMSG NickServ :id haggisbot PASSWORD\n");
sleep(1);
// Join channel
sendcommand($socket,"JOIN #bostonglob\n");
$justjoined = true;
sleep(1.5);
// Force an endless while
$floodfilters = array();
while(1) {
	// Continue the rest of the script here
	while($data = fgets($socket, 128)) {
		while (!strpos($data, "\n")) {
			$data .= fgets($socket, 128);
		}
		if (strpos($data, "ERROR :Closing Link: ") === 0 || !$socket) {
			echo "Fatal error occurred at ".date("r")." ".substr($data, strlen(substr($data, 0, strpos($data, " ", 23)+1)))."<br />";
			echo "Trying to re-connect.<br /><br />";
			// Closing and reopening the socket
			fclose($socket);
			$socket = @fsockopen("irc.freenode.net", 6667);
			if ($socket) {
				// Send auth info
				sendcommand($socket,"USER haggisbot \"EMAIL\" haggisbot :HaggisBot 0.6 by Mad Haggis Enterprises\n");
				sendcommand($socket,"NICK haggisbot\n");
				sendcommand($socket,"PRIVMSG NickServ :id haggisbot PASSWORD\n");
				// Join channel
				sendcommand($socket,"JOIN #bostonglob\n");
				$justjoined = true;
				break;
			} else {
				echo "Fatal error: cannot reconnect.  Trying again in 5 seconds.<br /><br />";
				sleep(5);
				$socket = @fsockopen("irc.freenode.net", 6667);
				if ($socket) {
					// Send auth info
					sendcommand($socket,"USER haggisbot \"EMAIL\" haggisbot :HaggisBot 0.6 by Mad Haggis Enterprises\n");
					sendcommand($socket,"NICK haggisbot\n");
					sendcommand($socket,"PRIVMSG NickServ :id haggisbot PASSWORD\n");
					// Join channel
					sendcommand($socket,"JOIN #bostonglob\n");
					$justjoined = true;
					break;
				} else {
					echo "Giving up.";
					closechat($socket);
				}
			}
		}
		if (censor($data) != $data) {
			$ex = explode(" ", $data);
			$data = censor($data);
			autokick($socket, trim($ex[0]), "Bad language");
			logline($data);
			continue;
		}
	/*	if (trim($ex[0]) != $floodfilter[0] && (trim($ex[1]) == "JOIN" || trim($ex[1]) == "PART" || trim($ex[1]) == "QUIT" || trim($ex[1]) == "NICK" || trim($ex[1]) == "PRIVMSG" || trim($ex[1]) == "NOTICE")) {
			$floodfilter[0] = trim($ex[0]);
			$floodfilter[1] = 0;
			$floodfilter[2] = time();
		}*/
		$ex = explode(" ", $data);
		if (!isset($floodfilters[md5(trim($ex[0]))])) {
			$floodfilters[md5(trim($ex[0]))] = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
		}
		foreach ($floodfilters as $filterkey => &$floodfilter) {
			if ($filterkey == md5(trim($ex[0]))) {
				$floodfilter[5] = $floodfilter[4];
				$floodfilter[4] = $floodfilter[3];
				$floodfilter[3] = $floodfilter[2];
				$floodfilter[2] = $floodfilter[1];
				$floodfilter[1] = time();
				$floodfilter[0]++;
				if ($floodfilter[0] > 5 && $floodfilter[1] < $floodfilter[5] + 5 && strpos($ex[0], "!") && !strpos(trim($ex[0]), "@services.") && !strpos(trim($ex[0]), "@freenode/") && !checkauth(trim($ex[0]))) {
					autokick($socket, trim($ex[0]), "Flood limit reached");
				}
			}
		}
		foreach ($bans as $ban_key => $ban) {
			if ($ban[1] < time()) {
				sendcommand($socket, "MODE #bostonglob -b ".$ban[0]."\n");
				unset($bans[$ban_key]);
			}
		}
		logline($data);
		flush();
		$ex = explode(" ", $data);
		$command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
		/*if (strpos($data, "0") && (!ctype_digit(substr($data, strpos($data, "0")+2, 1)) || substr($data, strpos($data, "0")+2, 1) == 0 || substr($data, strpos($data, "0")+2, 1) == 8 || substr($data, strpos($data, "0")+2, 1) == 9)) {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1)." said \"".((substr($command, 3, 1) == "8" || substr($command, 3, 1) == "9") ? substr($command, 1, 3) : substr($command, 1, 2)).",01".trim(substr(str_replace(array("00", "08", "09"), "0", $data), strpos(str_replace(array("00", "08", "09"), "0", $data), "0") + 2))."\"\n");
			$data = str_replace("0", "", str_replace(array("00", "08", "09"), "0", $data));
		}
		if (strpos($data, "11") || strpos($data, "15")) {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1)." said \"".substr($command, 1, 3).",1".trim(substr($data, strpos($data, substr($command, 1, 3)) + 3))."\"\n");
			$data = str_replace(array("15", "11"), "", $data);
		}*/
		$data = str_replace(array("", "", ""), "", $data);
		$data = preg_replace("/\[0-9]{1,2}(,[0-9]{1,2})?/", "", $data);
		// Separate all data
		$ex = explode(" ", $data);
		// Send PONG back to the server
		if($ex[0] == "PING"){
			sendcommand($socket, "PONG ".$ex[1]."\n");
		}
		// Say something in the channel
		$command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
		if (trim($ex[1]) == "JOIN") {
			global $kicked;
			if ($kicked) {
				sendcommand($socket, "PRIVMSG #bostonglob :Y u kick me? ".$kicked." is a nub!\n");
				$kicked = false;
			} else {
				$ip = array();
				foreach (str_split(substr($ex[0], strpos($ex[0], "!") + 3, 8), 2) as $ipchunk) {
					$ip[] = hexdec($ipchunk);
				}
				if (strpos($ex[0], "midco.net") || strpos(gethostbyaddr(implode($ip, ".")), "midco.net")) {
					sendcommand($socket, "PRIVMSG #bostonglob :Hai Dan\n");
				} elseif (strpos($ex[0], ".nwrk.east.verizon.net")) {
					sendcommand($socket, "PRIVMSG #bostonglob :Hai Non-Dan\n");
				} else {
					sendcommand($socket, "PRIVMSG #bostonglob :Hello, ".substr($ex[0], 1, strpos($ex[0], "!") - 1)."!\n");
					if (substr($ex[0], 1, strpos($ex[0], "!") - 1) == "haggisbot") {
						sendcommand($socket, "PRIVMSG #bostonglob :Wait... Why am I greeting myself?\n");
					} else {
						sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Welcome to the Boston Glob Chat.\n",
													"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Type !rank to see which commands you can use.\n",
													"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Type !rules to see the chat rules.\n"));
					}
				}
			}
		}
		if (trim($ex[1]) == "JOIN" || trim($ex[1]) == "PART" || trim($ex[1]) == "QUIT" || trim($ex[1]) == "NICK" || trim($ex[1]) == "KICK" || trim($ex[1]) == "MODE") {
			sendcommand($socket, "NAMES #bostonglob\n");
		}
		if (trim($ex[1]) == "KICK" && strtolower(trim($ex[3])) == "haggisbot") {
			global $kicked;
			$kicked = substr($ex[0], 1, strpos($ex[0], "!") - 1);
			sendcommands($socket, array("PRIVMSG ChanServ :unban #bostonglob\n",
										"PRIVMSG ChanServ :invite #bostonglob\n"));
		}
		if (strpos(substr($data, strpos($data, " ")), "INVITE haggisbot :#bostonglob") === 1) {
			sendcommand($socket, "JOIN #bostonglob\n");
			$justjoined = true;
		}
		if (strpos($data, ".freenode.net 353 haggisbot = #bostonglob :")) {
			global $USERSINCHAT;
			$USERSINCHAT = ltrim(trim(str_replace(array("haggisbot ", "@@haggisbot "), "@haggisbot ", substr($data, strpos($data, "haggisbot = #bostonglob :") + 24))), ":");
			if ($justjoined == true) {
				foreach (explode(" ", $USERSINCHAT) as $user) {
					if (ltrim($user, "@+") == "haggisbot") {
						continue;
					}
					sendcommand($socket, "PRIVMSG ".ltrim($user, "@+")." :PING ".time()."\n");
				}
				$justjoined = false;
			}
		}
		if ((trim($ex[1]) == "QUIT" || trim($ex[1]) == "PART") && substr($ex[0], 1, strpos($ex[0], "!") - 1) != "haggisbot") {
			sendcommand($socket, "PRIVMSG #bostonglob :Goodbye ".substr($ex[0], 1, strpos($ex[0], "!") - 1)."!  :'(\n");
		}
		if (trim($ex[1]) == "NICK") {
			$ip = array();
			foreach (str_split(substr($ex[0], strpos($ex[0], "!") + 3, 8), 2) as $ipchunk) {
				$ip[] = hexdec($ipchunk);
			}
			if (strpos($ex[0], "midco.net") || strpos(gethostbyaddr(implode($ip, ".")), "midco.net")) {
				sendcommand($socket, "PRIVMSG #bostonglob :Hai Dan\n");
			} elseif (strpos($ex[0], ".nwrk.east.verizon.net")) {
				sendcommand($socket, "PRIVMSG #bostonglob :Hai Non-Dan\n");
			} elseif (strpos($ex[2], "Guest") === 1) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1)." got NickSERV'd!\n");
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :Oh, ".substr($ex[0], 1, strpos($ex[0], "!") - 1).", you'd rather be known as ".trim(substr($ex[2], 1))."?  That's fine with me.\n");
			}
		}
		if (trim($ex[1]) == "MODE" && $ex[4] && trim($ex[4]) != "haggisbot") {
			/*$modechanged = trim($ex[3]);
			$modeon = trim($ex[4]);
			if ($modechanged == "+o") {
				$modestring = "made {USER} an operator!";
			} elseif ($modechanged == "-o") {
				$modestring = "took away operator status from {USER}!";
			} elseif ($modechanged == "+v") {
				$modestring = "made {USER} a VIP!";
			} elseif ($modechanged == "-v") {
				$modestring = "took away VIP status from {USER}!";
			} elseif ($modechanged == "+b") {
				if (substr($modeon, 0, 1) == "%") {
					$modestring = "muted {USER}.";
					$modeon = substr($modeon, 1);
				} else {
					$modestring = "banned {USER}.";
				}
			} elseif ($modechanged == "-b") {
				if (substr($modeon, 0, 1) == "%") {
					$modestring = "unmuted {USER}.";
					$modeon = substr($modeon, 1);
				} else {
					$modestring = "unbanned {USER}.";
				}
			}*/
			$modechanged = whatmode($data);
			//sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1)." ".str_replace("{USER}", $modeon, $modestring)."\n");
			sendcommand($socket, "PRIVMSG #bostonglob :".$modechanged);
			//if (strpos($modechanged, "o") || strpos($modechanged, "v")) {
			//	sendcommand($socket, "NOTICE ".trim($modeon)." :Use the !rank command to find out your abilities!\n");
			//}
		}
		foreach ($floodfilters as $filterkey => &$floodfilter) {
			if ($filterkey == md5(trim($ex[0])) && $floodfilter[1] - 1 <= $floodfilter[2] && strpos($ex[0], "!") && !strpos(trim($ex[0]), "@services.") && !strpos(trim($ex[0]), "@freenode/") && !checkauth(trim($ex[0])) && strpos($ex[0], "haggisbot!n=haggisbo@") !== 1) {
				if ((!isset($floodfilter[6]) || $floodfilter[6] < time() - 1800) && $ex[1] != "QUIT" && $ex[1] != "PART") {
					$floodfilter[6] = time();
					sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Just a notice, I will ignore you if you use commands multiple times per second.  This notice is sent once per half hour. (maximum)\n");
				}
				continue 2;
			}
		}
		foreach ($bans as $ban) {
			if (strpos($name, "@gateway/web/ajax/mibbit.com/")) {
				if (strpos($ban[0], "!".substr($ex[0], strpos($ex[0], "!") + 1, -16)) !== false) {
					continue 2;
				}
			} else {
				if (strpos($ban[0], "@".substr($ex[0], strpos($ex[0], "@") + 1)) !== false) {
					continue 2;
				}
			}
		}
		global $dan;
		if (!$dan) {
			$dan = array();
		}
		$isdan = false;
		if (strpos($ex[0], "@gateway/web/ajax/mibbit.com/")) {
			$ip = array();
			foreach (str_split(substr($ex[0], strpos($ex[0], "!") + 3, 8), 2) as $ipchunk) {
				$ip[] = hexdec($ipchunk);
			}
			$isdan = strpos(gethostbyaddr(implode($ip, ".")), "midco.net");
		}
		if ((strpos($ex[0], "midco.net") || $isdan) && trim($ex[1]) != "QUIT" && trim($ex[1]) != "PART" && trim($ex[1]) != "NICK") {
			$dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))] = substr($ex[0], 1, strpos($ex[0], "!") - 1);
		} elseif (strpos($ex[0], "midco.net") && trim($ex[1]) == "NICK") {
			unset($dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))]);
			$dan[md5(trim($ex[2]))] = trim($ex[2]);
		} else {
			if (isset($dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))])) {
				unset($dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))]);
			}
		}
		if (trim($ex[1]) == "KICK" && isset($dan[md5(strtolower(trim($ex[3])))])) {
			unset($dan[md5(strtolower(trim($ex[3])))]);
		}
		if (strtolower($command) == ":!issues" && count($ex) == 4) {
			sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issues===\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :1-No date\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :2-October 2002\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :3-November 2002\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :4-Also November 2002\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :5-December 2002\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :6-It's retro!\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :7-January 2003\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :8-October 2003\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :9-December 2003\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :10-April 2004\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :11-May 2008\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :For more information, type !issue <issue number>\n"));
		}
		if (strtolower($command) == ":!issue" && count($ex) == 5) {
			switch (trim($ex[4], "<>")) {
			case 1:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 1===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: No date\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/01/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/01/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 23\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 2:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 2===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: October 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/02/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/02/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 21\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 3:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 3===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: November 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/03/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/03/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 27\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 4:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 4===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: Also November 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/04/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/04/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 43\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 5:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 5===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: December 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/05/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/05/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 37\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 6:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 6===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: It's retro!\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/06/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/06/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 23\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 7:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 7===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: January 2003\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/07/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/07/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 51\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			/*case 8:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 8===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: October 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/02/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/02/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 21\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 9:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 2===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: October 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/02/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/02/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 21\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			case 10:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 2===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: October 2002\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/02/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/02/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 21\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;*/
			case 11:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue 11===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Date: May 2008\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Online: http://www.the-boston-glob.co.cc/issues/11/\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Printable: http://www.the-boston-glob.co.cc/issues/11/index.pdf\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Pages: 20\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Double click links to go to them.\n"));
				break;
			default:
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Issue ".trim(ltrim($ex[4], "0"))."===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :I'm sorry, but I have no information on issue number ".ltrim($ex[4], "0")."\n"));
			}
		}
		if (strtoupper($command) == ":VERSION") {
			sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :VERSION HaggisBot 0.6 by Mad Haggis Enterprises (http://www.the-boston-glob.co.cc/)\n");
		}
		if (strpos($data, ".freenode.net 401 haggisbot ")) {
			sendcommand($socket, "PRIVMSG #bostonglob :Who's ".trim($ex[3]).", anyway?\n");
		}
		if (strtolower($command) == ":!leave" && count($ex) == 4) {
			global $dan;
			if (checkauth($data)) {
				sendcommands($socket, array("PRIVMSG ".$ex[2]." :Goodbye.\n",
											"PART #bostonglob :Leaving on my master's request.\n"));
			} elseif (isset($dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))])) {
				$kicked = substr($ex[0], 1, strpos($ex[0], "!") - 1);
				sendcommands($socket, array("PART #bostonglob :Leaving 'cuz Dan told me to.\n",
											"JOIN #bostonglob\n",
											"PRIVMSG ChanServ :unban #bostonglob\n",
											"PRIVMSG ChanServ :invite #bostonglob\n"));
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION decides not to leave, even though ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." told him to.\n");
			}
		}
		if (strtolower($command) == ":!reboot" && count($ex) == 4) {
			if (checkauth($data)) {
				sendcommands($socket, array("PRIVMSG ".$ex[2]." :Goodbye.\n",
											"QUIT :[Terminator] AHLL BE BAHK.\n"));
				echo "<script type=\"text/javascript\">window.location.reload();</script>";
				sleep(1);
				closechat($socket);
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION decides not to leave, even though ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." told him to.\n");
			}
		}
		if (strtolower($command) == ":!users" && count($ex) == 4) {
			global $USERSINCHAT;
			if (checkauth($data) || checkvip($data)) {
				sendcommand($socket, respond($data, "Users currently in chat: ".implode(", ", explode(" ", $USERSINCHAT))."\n"));
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION thinks you should look in the right pane of your chat screen for the user list..\n");
			}
		}
		if ($command == ":!kick") {
			if (checkauth($data)) {
				sendcommands($socket, array("PRIVMSG #bostonglob :ACTION punches ".trim($ex[4])."\n",
											"PRIVMSG #bostonglob :ACTION kicks ".trim($ex[4])."\n",
											((strtolower(trim($ex[4])) == "haggisbot" || strtolower(trim($ex[4])) == "nightgunner5" || strtolower(trim($ex[4])) == "chanserv") ? ((strtolower(trim($ex[4])) == "haggisbot") ?
											"PRIVMSG #bostonglob :ACTION says \"Ow!\"\n" :
											((strtolower(trim($ex[4])) == "nightgunner5") ? "PRIVMSG #bostonglob :ACTION does no visible damage\n" :
											"PRIVMSG #bostonglob :Nothing interesting happens.\n"))
											: ((trim(substr($data, strpos($data, $ex[4]) + strlen($ex[4])))) ?
											"KICK #bostonglob ".trim($ex[4])." :Requested by ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." for reason: ".trim(substr($data, strpos($data, $ex[4]) + strlen($ex[4])))."\n" : 
											"KICK #bostonglob ".trim($ex[4])." :Requested by ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." for no apparent reason.\n"))));
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION thinks he would stub his toe and decides not to kick ".trim($ex[4])."\n");
			}
		}
		if (strtolower($command) == ":!say") {
			if (checkvip($data) || checkauth($data)) {
				sendcommand($socket, "PRIVMSG #bostonglob :".((trim(substr($data, strpos($data, $command) + 5))) ? trim(substr($data, strpos($data, $command) + 5)) : "Say what?")."\n");
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION believes in free speech and refuses to say what ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." tells him to say.\n");
			}
		}
		if (strtolower($command) == ":!md5") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".md5(trim(substr($data, strpos($data, $command) + 5)))."\n");
		}
		if (strtolower($command) == ":!isdan") {
			global $dan;
			if (((count($ex) == 4 || !trim($ex[4])) || (checkuser(trim($ex[4])) == substr($ex[0], 1, strpos($ex[0], "!") - 1))) && $dan[md5(substr($ex[0], 1, strpos($ex[0], "!") - 1))]) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": You are dan.\n");
			} elseif (count($ex) == 5 && checkuser(trim($ex[4])) && $dan[md5(checkuser(trim($ex[4])))]) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".checkuser(trim($ex[4]))." is dan.\n");
			} elseif (count($ex) == 4 || !trim($ex[4])  || checkuser(trim($ex[4])) == substr($ex[0], 1, strpos($ex[0], "!") - 1)) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": You are not dan.\n");
			} elseif (count($ex) == 5 && checkuser(trim($ex[4])) == "haggisbot") {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": I am not dan.\n");
			} elseif (count($ex) == 5 && checkuser(trim($ex[4]))) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".checkuser(trim($ex[4]))." is not dan.\n");
			} elseif (count($ex) == 5 && !checkuser(trim($ex[4]))) {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".trim($ex[4])." is not in the chat as far as I can see.\n");
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": You're using that command wrong.  Try typing \"!help isdan\".\n");
			}
		}
		if (strtolower($command) == ":!kickdan") {
			if (checkauth($data)) {
				global $dan;
				foreach ($dan as $danmd5 => $danuname) {
					sendcommand($socket, "KICK #bostonglob ".$danuname."\n");
					unset($dan[$danmd5]);
				}
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :lolwut\n");
			}
		}
		if (strtolower($command) == ":!sha1") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".sha1(trim(substr($data, strpos($data, $command) + 5)))."\n");
		}
		if (strtolower($command) == ":!reverse") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".strrev(trim(substr($data, strpos($data, $command) + 9)))."\n");
		}
		if (strtolower($command) == ":!en64") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".base64_encode(trim(substr($data, strpos($data, $command) + 6)))."\n");
		}
		if (strtolower($command) == ":!un64" || strtolower($command) == ":!de64") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".base64_decode(trim(substr($data, strpos($data, $command) + 6)))."\n");
		}
		if (strtolower($command) == ":!rot13") {
			sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".str_rot13(trim(substr($data, strpos($data, $command) + 7)))."\n");
		}
		if (strtolower($command) == ":!facepalm" && count($ex) == 4) {
			sendcommand($socket, "PRIVMSG #bostonglob :ACTION slaps ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." in the face with his palm.\n");
		}
		if (strtolower($command) == ":!faceplam" && count($ex) == 4) {
			sendcommand($socket, "PRIVMSG #bostonglob :ACTION slaps ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." in the face with his plam.  What the heck is a plam?\n");
		}
		if (strtolower($command) == ":!fail" && count($ex) == 5) {
			sendcommand($socket, "PRIVMSG #bostonglob :".((checkuser(trim($ex[4])) && strtolower(trim($ex[4])) != "haggisbot") ? checkuser(trim($ex[4])) : substr($ex[0], 1, strpos($ex[0], "!") - 1))." fails at life.\n");
		}
		if (strtolower($command) == ":!calc") {
			$expression = preg_replace('/[^0-9\.\+\/\*\-\ ]/', '', trim(substr($data, strpos($data, $command) + 7)));
			if ($expression == trim(substr($data, strpos($data, $command) + 7))) {
				eval('$result = ' . $expression . ';');
				sendcommand($socket, "PRIVMSG #bostonglob :".substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".$result."\n");
			}
		}
		if (strtolower($command) == ":!rainbow" && (checkauth($data) || checkvip($data))) {
			sendcommand($socket, "PRIVMSG #bostonglob :".ircrainbow(trim(substr($data, strpos($data, $command) + 9)), true, false)."\n");
		}
		if (strtolower($command) == ":!rules" && count($ex) == 4) {
			sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===Boston Glob Chat Rules===\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Flooding is against the rules.  For more information, type !rule flooding.\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Swearing is against the rules.  For more information, type !rule language.\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Flaming, flamebaiting, and otherwise abusing the chat is against the rules.  For more information, type !rule abuse.\n",
										"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Impersonating Boston Glob staff members (including me) is against the rules.  For more information, type !rule impersonation.\n"));
		}
		if (strtolower($command) == ":!rule" && count($ex) == 5) {
			switch (trim($ex[4])) {
			case "flooding":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===No flooding===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Flooding is against the rules.  If you are found to be flooding too much, you will be kicked and muted.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Flooding is the act of rapidly sending messages and spamming the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you send commands to me more than once per second, I will not respond to you.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you flood too far past the limit before I have a chance to take action, you will be kicked and banned.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Bans and mutes last 5 minutes each and will continue to be active even if you change usernames or log out and log back into the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you are muted and wish to come back in to see the conversation, you can refresh the page.  Only you will see the text you type until your mute is over.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Mutes can be ended early by a chat operator, bans cannot.\n"));
				break;
			case "language":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===No swearing===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Bad language is against the rules.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you swear or use an offensive name, you will be kicked out of chat and given a five minute mute.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Exessive swearing will lead to a five minute ban.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you try to make me swear, I will censor the bad words.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Bans and mutes last 5 minutes each and will continue to be active even if you change usernames or log out and log back into the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you are muted and wish to come back in to see the conversation, you can refresh the page.  Only you will see the text you type until your mute is over.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Mutes can be ended early by a chat operator, bans cannot.\n"));
				break;
			case "abuse":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===No flaming, flamebaiting, or abuse===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you continuously flame or flamebait in chat, you will be muted or banned.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Bans and mutes last 5 minutes each and will continue to be active even if you change usernames or log out and log back into the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Permanent bans will be issued if you continue abusing the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you are muted and wish to come back in to see the conversation, you can refresh the page.  Only you will see the text you type until your mute is over.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Mutes can be ended early by a chat operator, bans cannot.\n"));
				break;
			case "impersonation":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===No impersonating Boston Glob staff members===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :DO NOT impersonate Boston Glob staff members.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :If you are found to be impersonating Boston Glob staff members, you will be banned from the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :All staff members will have a gold star next to their name on the new client, or an @ sign before their name in the old chat client.\n"));
				break;
			default:
				sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Sorry, but I do not know of that rule.\n");
			}
		}
		if ((strtolower($command) == ":!rank" && (count($ex) == 4 || count($ex) == 5)) || ((strtolower($command) == ":!help" || strtolower($command) == ":!commands") && count($ex) == 4)) {
			if (count($ex) == 4) {
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :You are ".((checkauth($data)) ? "an operator" : ((checkvip($data)) ? "a VIP" : "a reader")).".\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :You can use the following commands:\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :".((checkauth($data)) ? "!issues, !issue <number>, !leave, !say <text>, ping, pong, !kick <user> [reason], !users, !raw <command>, !rank [username], !reboot, !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !rainbow <string>, !facepalm, !fail <user>, !mute <user>, !unmute <user>, !ban <user>, !unban <user>, !banlist, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username], !kickdan" : ((checkvip($data)) ? "!issues, !issue <number>, !say <text>, ping, pong, !users, !rank [username], !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !rainbow <string>, !facepalm, !fail <user>, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username]" : "!issues, !issue <number>, ping, pong, !rank [username], !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !facepalm, !fail <user>, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username]"))."\n"));
			} elseif (strtolower(trim($ex[4])) == "haggisbot") {
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :haggisbot is an all-powerful robot.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :haggisbot can any commands he wants to.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Did you really need to ask?\n"));
			} elseif (strtolower(trim($ex[4])) == "chanserv") {
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :ChanServ is an all-powerful potato.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :ChanServ can protect the channel from anything.\n"));
			} elseif (!checkuser(trim($ex[4]))) {
				sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :I do not know of anyone by the name of ".trim($ex[4]).".\n");
			} else {
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :".checkuser(trim($ex[4]))." is ".((checkauth(trim($ex[4]), true)) ? "an operator" : ((checkvip(trim($ex[4]), true)) ? "a VIP" : "a reader")).".\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :".checkuser(trim($ex[4]))." can use the following commands:\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :".((checkauth(trim($ex[4]), true)) ? "!issues, !issue <number>, !leave, !say <text>, ping, pong, !kick <user> [reason], !users, !raw <command>, !rank [username], !reboot, !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !rainbow <string>, !facepalm, !fail <user>, !mute <user>, !unmute <user>, !ban <user>, !unban <user>, !banlist, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username], !kickdan" : ((checkvip(trim($ex[4]), true)) ? "!issues, !issue <number>, !say <text>, ping, pong, !users, !rank [username], !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !rainbow <string>, !facepalm, !fail <user>, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username]" : "!issues, !issue <number>, ping, pong, !rank [username], !md5 <string>, !sha1 <string>, !reverse <string>, !en64 <string>, !de64 <string>, !rot13 <string>, !calc <expression>, !facepalm, !fail <user>, !blow <key> <text>, !unblow <key> <text>, !rules, !rule <rulename>, !isdan [username]"))."\n"));
			}
		}
		if (strtolower($command) == ":!help" && count($ex) == 5) {
			switch (ltrim(strtolower(trim($ex[4])), "!")) {
			case "help":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!help===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Lists the available commands for your user level.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!help <command-name>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Gives help on how to use <command-name>.\n"));
				break;
			case "commands":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!commands===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Lists the available commands for your userlevel.\n"));
				break;
			case "issues":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!issues===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Lists the volumes of The Boston Glob magazine.\n"));
				break;
			case "issue":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!issue <issue-number>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Gives more detailed information on volume <issue-number> of The Boston Glob magazine.\n"));
				break;
			case "leave":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!leave===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Makes haggisbot leave the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "say":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!say <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Makes haggisbot say <text> into the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the VIP user level or higher.\n"));
				break;
			case "ping":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===ping===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :A simple game where haggisbot replies with pong. Haggisbot follows capitalization and will even recognize this command with a 1 for the i.\n"));
				break;
			case "pong":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===pong===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :A simple game where haggisbot replies with ping. Haggisbot follows capitalization and will even recognize this command with a 0 for the o.\n"));
				break;
			case "kick":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!kick <username> [reason]===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Kicks <username> from the chat for (optional) [reason].\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "users":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!users===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays haggisbot's view of the userlist for the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the VIP user level or higher.\n"));
				break;
			case "raw":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!raw <raw-command>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Makes haggisbot send the <raw-command> directly to the chat server.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "rank":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rank===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Lists the available commands for your user level.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rank <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Lists the available commands for <username>'s user level.\n"));
				break;
			case "isdan":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!isdan===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Checks to see if you are Dan.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!isdan <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Checks to see if <username> is Dan.\n"));
				break;
			case "kickdan":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!kickdan===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Kicks Dan from the chat.\n"));
				break;
			case "reboot":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!reboot===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Reboots haggisbot completely.  If there is a fatal error in the code, haggisbot must be reset manually.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "md5":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!md5 <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays the MD5 hash sum of <text>.\n"));
				break;
			case "md5":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!sha1 <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays the SHA1 hash sum of <text>.\n"));
				break;
			case "reverse":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!reverse <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays <text>, reversed.\n"));
				break;
			case "en64":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!en64 <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays the base64-encoded version of <text>.\n"));
				break;
			case "de64":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!de64 <en64-result>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Decodes <en64-result>.\n"));
				break;
			case "rot13":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rot13 <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Rotates all letters in <text> 13 places.\n"));
				break;
			case "calc":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!calc <numeric-expression>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Calculates the answer to <numeric-expression>.  Allowed characters are numbers 0-9, +, -, *, and /.\n"));
				break;
			case "rainbow":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rainbow <text>...===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Displays <text> with each letter a different color of the rainbow.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the VIP user level or higher.\n"));
				break;
			case "facepalm":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!facepalm===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Makes haggisbot slap your face with his palm.\n"));
				break;
			case "fail":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!fail <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Tells <username> that they fail at life.\n"));
				break;
			case "mute":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!mute <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Stops <username> from talking for 5 minutes.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "unmute":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!unmute <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Ends <username>'s mute early. (see !mute)\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "ban":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!ban <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Stops <username> from entering the chat for 5 minutes.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "unban":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!unban <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Ends <username>'s ban early. (see !ban)\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "banlist":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!banlist <username>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Responds privately with a list of current bans and mutes in the chat.\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :This command requires the operator user level.\n"));
				break;
			case "blow":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!blow <key> <text>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Uses blowfish encryption to encrypt <text> with <key>.\n"));
				break;
			case "unblow":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!unblow <key> <text>===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Uses blowfish encryption to decrypt <text> with <key>.\n"));
				break;
			case "rules":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rules===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Responds with the rules for the chat.\n"));
				break;
			case "rule":
				sendcommands($socket, array("NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :===!rule===\n",
											"NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :Gives more information on a chat rule.\n"));
				break;
			default:
				sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :I have no help topic on ".$ex[4].".\n");
			}
		}
		if (strtolower($command) == ":!raw") {
			if (checkauth($data)) {
				sendcommand($socket, trim(substr($data, strpos($data, $command) + 5))."\n");
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :ACTION believes in free speech and refuses to say what ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." tells him to say.\n");
			}
		}
		if (strtolower($command) == ":!mute" && count($ex) == 5) {
			if (checkauth($data)) {
				$mutename = trim($ex[4]);
				$bans[] = array("%".$mutename, time() + 300);
				$rawcmd = "MODE #bostonglob +b %".$mutename."\n";
				fputs($socket, $rawcmd);
				logline(censor($rawcmd), true);
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :What?  I can't hear you, ".substr($ex[0], 1, strpos($ex[0], "!") - 1)."!  I'm a bit deaf in this ear.\n");
			}
		}
		if (strtolower($command) == ":!unmute" && count($ex) == 5) {
			if (checkauth($data)) {
				global $bans;
				$mutename = trim($ex[4]);
				foreach ($bans as $bankey => $ban) {
					if ($ban[0] == "%".$mutename) {
						unset($bans[$bankey]);
					}
				}
				$rawcmd = "MODE #bostonglob -b %".$mutename."\n";
				fputs($socket, $rawcmd);
				logline(censor($rawcmd), true);
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :What?  I can't hear you, ".substr($ex[0], 1, strpos($ex[0], "!") - 1)."!  I'm a bit deaf in this ear.\n");
			}
		}
		if (strtolower($command) == ":!ban" && count($ex) == 5) {
			if (checkauth($data)) {
				$mutename = trim($ex[4]);
				$bans[] = array($mutename, time() + 300);
				$rawcmd = "MODE #bostonglob +b ".$mutename."\n";
				fputs($socket, $rawcmd);
				logline(censor($rawcmd), true);
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :Sorry, ".substr($ex[0], 1, strpos($ex[0], "!") - 1).", but you're banned from using that command.\n");
			}
		}
		if (strtolower($command) == ":!unban" && count($ex) == 5) {
			if (checkauth($data)) {
				global $bans;
				$mutename = trim($ex[4]);
				foreach ($bans as $bankey => $ban) {
					if ($ban[0] == $mutename) {
						unset($bans[$bankey]);
					}
				}
				$rawcmd = "MODE #bostonglob -b ".$mutename."\n";
				fputs($socket, $rawcmd);
				logline(censor($rawcmd), true);
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :Sorry, ".substr($ex[0], 1, strpos($ex[0], "!") - 1).", but you're banned from using that command.\n");
			}
		}
		if (strtolower($command) == ":!banlist" && count($ex) == 4) {
			if (checkauth($data)) {
				global $bans;
				if (!$bans) {
					sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :I do not know of any bans or mutes in this channel.\n");
				}
				foreach ($bans as $ban) {
					sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :".((strpos($ban[0], "%") === 0) ? "Muted for " : "Banned for ").($ban[1] - time())." more seconds: ".$ban[0]."\n");
					sleep(0.1);
				}
			} else {
				sendcommand($socket, "PRIVMSG #bostonglob :Sorry, ".substr($ex[0], 1, strpos($ex[0], "!") - 1).", but you're banned from using that command.\n");
			}
		}
		if ($command == ":PING" && $ex[1] == "PRIVMSG") {
			sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :PING ".$ex[4]."\n");
		}
		if ($command == ":TIME") {
			sendcommand($socket, "NOTICE ".substr($ex[0], 1, strpos($ex[0], "!") - 1)." :TIME ".date("l, F jS, Y g:i:s A")."\n");
		}
		if (strtolower($command) == ":!blow" && count($ex) > 5) {
			$blow = new Blowfish(trim($ex[4]));
			$ex2 = $ex;
			unset($ex2[0]);
			unset($ex2[1]);
			unset($ex2[2]);
			unset($ex2[3]);
			unset($ex2[4]);
			$blow2 = $blow->encrypt(trim(implode(" ", $ex2)));
			sendcommand($socket, respond($data, substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".$blow2."\n"));
		}
		if (strtolower($command) == ":!unblow" && count($ex) > 5) {
			$blow = new Blowfish(trim($ex[4]));
			$ex2 = $ex;
			unset($ex2[0]);
			unset($ex2[1]);
			unset($ex2[2]);
			unset($ex2[3]);
			unset($ex2[4]);
			$blow2 = $blow->decrypt(trim(implode(" ", $ex2)));
			sendcommand($socket, respond($data, substr($ex[0], 1, strpos($ex[0], "!") - 1).": ".$blow2."\n"));
		}
		if ((strtolower($command) == ":ping" || strtolower($command) == ":p1ng") && trim($ex[1]) == "PRIVMSG" && trim($ex[2]) == "#bostonglob" && count($ex) == 4) {
			sendcommand($socket, "PRIVMSG #bostonglob :".str_replace(array("1", "i", "I"), array("0", "o", "O"), substr(trim($command), 1))."\n");
		}
		if ((strtolower($command) == ":pong" || strtolower($command) == ":p0ng") && trim($ex[1]) == "PRIVMSG" && trim($ex[2]) == "#bostonglob" && count($ex) == 4) {
			sendcommand($socket, "PRIVMSG #bostonglob :".str_replace(array("0", "o", "O"), array("1", "i", "I"), substr(trim($command), 1))."\n");
		}
		if ($currentdate != date('l, F jS, Y')) {
			echo "<script type=\"text/javascript\">window.location.reload();</script>";
			closechat($socket);
		}
		
		sleep(0.1);
	}
}

?>